<?php
class Warehouse_Service_ProductsBatchProccess
{
    protected $_option = null; // array
    protected $_quantity = 0; //调整差值
    protected $_error = null;
    protected $_productsBatch = null; //批次
    protected $_warehouseProduct = null; //货架
    protected $_onHold = false;
    protected $_wpstatus = 1; //货架库存状态

    public function __construct($params = null)
    {
        if (isset($params)) {
            foreach ($params as $key => $val) {
                $this->_option[$key] = $val;
            }
        }
    }

    /*
    * 库存调整
    * @param array(
       'wpbId' => null,
       'intQuantity' => null,
       'strReason' => null);
    *return array('ask'=>0,'msg'=>'message')
    */
    public function editStocket()
    {
        if (!$this->validatorStocket()) {
            return array('ask' => 0, 'msg' => $this->_error);
        }
        if (!$this->ProductsBatchTransaction()) {
            return array('ask' => 0, 'msg' => $this->_error);
        }
        return array('ask' => 1, 'msg' => '操作成功!');
    }

    /*
    * 库位调整
    * @param array(
       'wpbId' => null,
       'strWscode' => null,目标货架号
       'intQuantity'=>0 ,移动数量
       'strReason' => null);
    *return array('ask'=>0,'msg'=>'message')
    */
    public function moveShelfStocket()
    {
        if (!$this->validatorShelf()) {
            return array('ask' => 0, 'msg' => $this->_error);
        }
        if (!$this->shelfTransaction()) {
            return array('ask' => 0, 'msg' => $this->_error);
        }
        return array('ask' => 1, 'msg' => '操作成功!');
    }

    /*
    * 设置货架及批次数据
    */
    private function setData()
    {
        $wpbRow = Warehouse_Service_ProductsBatch::getById($this->_option['wpbId']);
        if (empty($wpbRow)) {
            $this->_error = "操作失败,未找到库存批次!";
            return false;
        }
        //设置批次
        $this->_productsBatch = $wpbRow;
        $pcondition = array(
            'warehouse_id' => $this->_productsBatch['warehouse_id'],
            'product_id' => $this->_productsBatch['product_id'],
            'ws_code' => $this->_productsBatch['ws_code'],
        );
        $warehouseProduct = Warehouse_Service_Products::getByCondition($pcondition);
        if (empty($warehouseProduct)) {
            $this->_error = "操作失败,未找到对应货架库存!";
            return false;
        }
        if ($warehouseProduct['wp_status'] == '2') {
            $this->_error = "操作失败,货架: " . $this->_productsBatch['ws_code'] . "进行盘点中.";
            return false;
        } elseif ($warehouseProduct['wp_status'] == '0') {
            $this->_error = "操作失败,货架库存: " . $this->_productsBatch['ws_code'] . "状态为不可用.";
            return false;
        }
        $this->_warehouseProduct = $warehouseProduct;
        return true;
    }

    /*
    * 验证移库位调整
    */
    private function validatorShelf()
    {
        $error = array();
        $validateArr = array();
        $validateArr[] = array('name' => '批次', 'value' => isset($this->_option['wpbId']) ? $this->_option['wpbId'] : '', 'regex' => array('require',));
        $validateArr[] = array('name' => '移动数量', 'value' => isset($this->_option['intQuantity']) ? $this->_option['intQuantity'] : '', 'regex' => array('require', 'positive1'));
        $validateArr[] = array('name' => '目标货架号', 'value' => isset($this->_option['strWscode']) ? $this->_option['strWscode'] : '', 'regex' => array('require',));
        $validateArr[] = array('name' => '原因', 'value' => isset($this->_option['strReason']) ? $this->_option['strReason'] : '', 'regex' => array('require',));
        $error = Common_Service_Validator::formValidator($validateArr);
        if (!empty($error)) {
            $this->_error = join(',', $error);
            return false;
        }
        $this->_option['strWscode'] = strtoupper($this->_option['strWscode']);
        if (!$this->setData()) {
            return false;
        }

        if ($this->_productsBatch['ws_code'] == $this->_option['strWscode']) {
            $this->_error = "操作失败,目标货位不能与原货位相同!";
            return false;
        }

        $condition = array(
            'ws_code' => $this->_option['strWscode'],
            'product_id' => $this->_productsBatch['product_id'],
        );
        $oldShelfRow = Warehouse_Service_Shelf::getByfield('ws_code', $this->_productsBatch['ws_code']);
        $newShelfRow = Warehouse_Service_Shelf::getByfield('ws_code', $this->_option['strWscode']);
        $wspRow = Warehouse_Service_Products::getByCondition(array('ws_code' => $this->_option['strWscode'], 'warehouse_id' => 1));

        if ($this->_productsBatch['wpb_quantity'] < $this->_option['intQuantity']) {
            $this->_error = "移动数量不可以大于可用数量!" . $this->_productsBatch['wpb_quantity'] . '>>' . $this->_option['intQuantity'];
            return false;
        }

        if (empty($newShelfRow)) {
            $this->_error = "货架号:" . $this->_option['strWscode'] . "不存在!";
            return false;
        } elseif ($newShelfRow['ws_statu'] != 1) {
            $this->_error = "货架号:" . $this->_option['strWscode'] . "不可用!";
            return false;
        }
        if (!empty($wspRow)) {
            if ($wspRow['wp_status'] == '2') {
                $this->_error = "操作失败,目标货架:" . $this->_option['strWscode'] . " 正在盘点中.";
                return false;
            }
            if ($wspRow['product_id'] != $this->_productsBatch['product_id'] && $wspRow['wp_status'] != '0') {
                $this->_error = "调入的货位必须是空货位，或者只有该产品!";
                return false;
            }
        }
        if (!Warehouse_Service_Shelf::getByJoinChooseCondition($condition, "count(*)")) {
            $this->_error = "货架号:" . $this->_option['strWscode'] . "与产品目录不符!";
            return false;
        } elseif ($newShelfRow['wsc_code'] != $oldShelfRow['wsc_code']) {
            $this->_error = "货架号:" . $this->_option['strWscode'] . "不符合库存应用类型!";
            return false;
        }
        $putawayoption = array(
            'putaway_status_in' => array('0','-1'),//草稿、未确认
            'ws_code' => $this->_option['strWscode'],
        );
        $pRows = Product_Service_Putaway::getByCondition($putawayoption, "*", '', 0, 0);
        if (!empty($pRows)) {
            if ($pRows[0]['product_id'] != $this->_productsBatch['product_id']) {
                $this->_error = "货架号:" . $this->_option['strWscode'] . " 已被 " . $pRows[0]['putaway_code'] . " 批次 " . $pRows[0]['putaway_lot_number'] . " 占用!";
                return false;
            }
        }

        //判断总库存全部数量是否够减
        $productStocket = Product_Service_ProductStocket::getByProductId($this->_productsBatch['product_id'], 1);
        if (!isset($productStocket['ps_quantity']) || ($productStocket['ps_quantity'] + $productStocket['ps_quantity_hold']) - $this->_option['intQuantity'] < 0) {
            $this->_error = '操作失败,总库存数量有误,库存少于批次!';
            return false;
        }
        $this->_onHold = ($productStocket['ps_quantity_hold'] > 0) ? true : false;

        //判断货架库存可用数量是否够减
        if (!isset($this->_warehouseProduct['wp_quantity']) || ($this->_warehouseProduct['wp_quantity'] - $this->_option['intQuantity']) < 0) {
            $this->_error = '操作失败,货架库存可用数量少于批次!';
            return false;
        }
        return true;

    }

    /*
    * 移库位调整事务
    */
    private function shelfTransaction()
    {
        $date = date("Y-m-d H:i:s");
        $WMProducts = new Warehouse_Model_Products();
        $dbAdapter = $WMProducts->getAdapter();
        $dbAdapter->beginTransaction();
        try {
            $note = "库存:" . $this->_option['intQuantity'] . "由" . $this->_productsBatch['ws_code'] . "移到" . $this->_option['strWscode'] . "|";
            $note .= "原因:" . $this->_option['strReason'];

            $wpbStatus = 1; //批次状态
            if ($this->_productsBatch['wpb_quantity_hold'] == 0 && $this->_productsBatch['wpb_quantity'] - $this->_option['intQuantity'] == 0) {
                $wpbStatus = 0;
            }
            //减批次可用数量,新建目标货架批次
            $updatabatch = array(
                'wpb_status' => $wpbStatus,
                'wpb_quantity' => $this->_productsBatch['wpb_quantity'] - $this->_option['intQuantity'],
                'wpb_last_update' => $date,
            );
            if (!Warehouse_Service_ProductsBatch::update($updatabatch, $this->_productsBatch['wpb_id'])) {
                $dbAdapter->rollback();
                $this->_error = '更新批次库存失败!';
                return false;
            }
            $this->createProductUseageLog($note, 3);
            //添加目标货架批次库存
            $addbatch = array(
                'warehouse_id' => $this->_productsBatch['warehouse_id'],
                'product_id' => $this->_productsBatch['product_id'],
                'putaway_code' => 'p' . date('Ymdhis'),
                'receiving_code' => 'R' . date('Ymdhis'),
                'putaway_lot_number' => 123,
                'ws_code' => $this->_option['strWscode'],
                'wpb_status' => 1,
                'wpb_quantity' => $this->_option['intQuantity'],
                'wpb_create_time' => $date,
                'wpb_last_update' => $date,
            );
            if (!Warehouse_Service_ProductsBatch::create($addbatch)) {
                $dbAdapter->rollback();
                $this->_error = '添加目标批次库存记录失败!';
                return false;
            }

            //更新原始货位库存
            $quantity = $this->_warehouseProduct['wp_quantity'] - $this->_option['intQuantity'];
            $wpNote = '|移动库存:'.$this->_option['intQuantity'].' 到货架:'.$this->_option['strWscode'].' 原因:'.$this->_option['strReason'];
            if ($this->_onHold == false && $quantity == 0 && $this->_warehouseProduct['wp_quantity_hold'] == 0 && $this->_productsBatch['wpb_quantity_hold'] == 0) {
                $this->_wpstatus = 0;
            } elseif ($this->_productsBatch['wpb_quantity_hold'] == 0 && $quantity == 0 && $this->_warehouseProduct['wp_quantity_hold'] == 0) {
                /*
                * 查询相关此货架产品是否有未发货订单
                */
                $this->getByShelfStatus();
            }
            if ($this->_wpstatus == '0') {
                $wpNote .= ' |状态修改为不可用';
            }
            $updateRow = array(
                'wp_status' => $this->_wpstatus,
                'wp_quantity' => $quantity,
                'wh_last_update' => $date,
            );
            if (!Warehouse_Service_Products::update($updateRow, $this->_warehouseProduct['wp_id'])) {
                $dbAdapter->rollback();
                $this->_error = '更新原货架库存失败!';
                return false;
            }
            //货架使用日志
            $WarehouseProductsLog = array(
                'wpl_refId' => 'move shelf stocket',
                'warehouse_id' => $this->_productsBatch['warehouse_id'],
                'ws_code' => $this->_productsBatch['ws_code'],
                'wpl_proc_type' => 0,
                'wpl_note' => '原' . $this->_warehouseProduct['wp_quantity'] . '修改为' . $quantity . $wpNote,
            );
            //写入货架使用日志
            if (!Warehouse_Service_Products::CreateWarehouseProductsLog($WarehouseProductsLog)) {
                $dbAdapter->rollback();
                $this->_error = '写入原货架使用日志失败!wpl';
                return false;
            }


            //更新目标库存
            $pcondition = array(
                //'product_id' => $this->_productsBatch['product_id'],
                'ws_code' => $this->_option['strWscode'],
            );
            $newWarehouseProductRows = Warehouse_Service_Products::getByCondition($pcondition);
            $quantity = 0;
            $currentQty=0;//原来的库存
            $wpNote = '';
            if (!empty($newWarehouseProductRows)) {
                if ($newWarehouseProductRows['product_id'] !=  $this->_productsBatch['product_id'] && $newWarehouseProductRows['wp_status'] !='0' ) {
                    $dbAdapter->rollback();
                    $this->_error ='目标货架:'.$this->_option['strWscode'].'状态异常,不允许操作!';
                    return false;
                }
                $currentQty = $newWarehouseProductRows['wp_quantity'];
                $quantity = $currentQty + $this->_option['intQuantity'];
                $quantityUpdateRow = array(
                    'wp_quantity' => $quantity,
                    'wh_last_update' => $date,
                );
                //如果之前放其它产品,则修改产品ID以及数量
                if ($newWarehouseProductRows['product_id'] !=  $this->_productsBatch['product_id'] ) {
                    $quantityUpdateRow['product_id'] = $this->_productsBatch['product_id'];
                    $quantityUpdateRow['wp_quantity'] = $this->_option['intQuantity'];
                    $currentQty=0;
                    $wpNote .= '|productId '.$newWarehouseProductRows['product_id'].' to '.$this->_productsBatch['product_id'];
                }
                if ($newWarehouseProductRows['wp_status'] == 0) {
                    $quantityUpdateRow['wp_status'] = 1;
                    $wpNote .= ' |状态修改为可用!';
                }
                if (!Warehouse_Service_Products::update($quantityUpdateRow, $newWarehouseProductRows['wp_id'])) {
                    $dbAdapter->rollback();
                    $this->_error = '更新目标货架库存失败!';
                    return false;
                }
            } else {
                $wpNote='|占用新货架!';
                $quantity = $this->_option['intQuantity'];
                $addWarehouseProduct = array(
                    'warehouse_id' => $this->_productsBatch['warehouse_id'],
                    'ws_code' => $this->_option['strWscode'],
                    'customer_id' => $this->_warehouseProduct['customer_id'],
                    'product_id' => $this->_productsBatch['product_id'],
                    'wp_quantity' => $this->_option['intQuantity'],
                    'wh_create_date' => $date,
                    'wh_last_update' => $date,
                );
                //添加库存产品
                if (!Warehouse_Service_Products::add($addWarehouseProduct)) {
                    $dbAdapter->rollback();
                    $this->_error = '添加目标货架库存记录失败!';
                    return false;
                }
            }

            //目标货架使用日志
            $WarehouseProductsLog = array(
                'wpl_refId' => 'move shelf stocket',
                'warehouse_id' => $this->_productsBatch['warehouse_id'],
                'ws_code' => $this->_option['strWscode'],
                'wpl_proc_type' => 1,
                'wpl_note' => '从货架' . $this->_warehouseProduct['ws_code'] . '转入' . $this->_option['intQuantity'] . '数量由:' . $currentQty . ' to ' . $quantity . $wpNote,
            );
            //写入货架使用日志
            if (!Warehouse_Service_Products::CreateWarehouseProductsLog($WarehouseProductsLog)) {
                $dbAdapter->rollback();
                $this->_error = '写入目标货架使用日志失败!wplog';
                return false;
            }

            $dbAdapter->commit();
            return true;
        } catch (Exception $e) {
            $dbAdapter->rollback();
            $this->_error = $e->getMessage();
            return false;
        }
    }

    /*
    * 验证库存调整
    */
    private function validatorStocket()
    {
        $error = array();
        $validateArr = array();
        $validateArr[] = array('name' => '批次', 'value' => isset($this->_option['wpbId']) ? $this->_option['wpbId'] : '', 'regex' => array('require',));
        $validateArr[] = array('name' => '原因', 'value' => isset($this->_option['strReason']) ? $this->_option['strReason'] : '', 'regex' => array('require',));
        $validateArr[] = array('name' => '数量', 'value' => isset($this->_option['intQuantity']) ? $this->_option['intQuantity'] : '', 'regex' => array('require', 'integer',));
        $error = Common_Service_Validator::formValidator($validateArr);
        if (!empty($error)) {
            $this->_error = join(',', $error);
            return false;
        }
        //设置批次
        if (!$this->setData()) {
            return false;
        }
        if ($this->_productsBatch['wpb_quantity'] == $this->_option['intQuantity']) {
            $this->_error = "操作失败,没有修改任何资料!";
            return false;
        }
        if ($this->_productsBatch['wpb_status'] != '1') {
            $this->_error = "操作失败,批次状态为可用时才可以修改!";
            return false;
        }

        //计算差值
        $this->_quantity = $this->_option['intQuantity'] - $this->_productsBatch['wpb_quantity'];
        //判断总库存可用数量是否够减
        $productStocket = Product_Service_ProductStocket::getByProductId($this->_productsBatch['product_id'], 1);
        if (!isset($productStocket['ps_quantity']) || $productStocket['ps_quantity'] + $this->_quantity < 0) {
            $this->_error = '操作失败,总库存可用数量少于调整差!';
            return false;
        }
        $this->_onHold = ($productStocket['ps_quantity_hold'] > 0) ? true : false;

        //判断货架库存可用数量是否够减
        if (!isset($this->_warehouseProduct['wp_quantity']) || $this->_warehouseProduct['wp_quantity'] + $this->_quantity < 0) {
            $this->_error = '操作失败,货架库存可用数量少于调整差!';
            return false;
        }
        return true;
    }

    /*
    * 库存调整事务
    */
    private function productsBatchTransaction()
    {
        $date = date("Y-m-d H:i:s");
        $WMProducts = new Warehouse_Model_Products();
        $dbAdapter = $WMProducts->getAdapter();
        $dbAdapter->beginTransaction();
        try {
            $note = '';
            $note .= "数量由" . $this->_productsBatch['wpb_quantity'] . "修改为" . $this->_option['intQuantity'] . "|";
            $note .= "原因:" . $this->_option['strReason'];

            $wpuProcType = ($this->_quantity > 0) ? '1' : '0';
            //更新批次
            $updatabatch = array(
                'wpb_quantity' => $this->_option['intQuantity'],
                'wpb_last_update' => $date,
            );
            if ($this->_option['intQuantity'] == 0 && $this->_productsBatch['wpb_quantity_hold'] == 0) {
                $updatabatch['wpb_status'] = 0; //状态变为空
            }
            if (!Warehouse_Service_ProductsBatch::update($updatabatch, $this->_productsBatch['wpb_id'])) {
                $dbAdapter->rollback();
                $this->_error = '更新批次库存失败!';
                return false;
            }
            $this->createProductUseageLog($note, $wpuProcType);

            //更新货架库存
            //如果总库存没有冻结数量则修改状态为不可用
            //判断是否要修改货架库存状态
            $wpNote = '';
            $this->_wpstatus = 1;
            if ($this->_onHold == false) {
                if ($this->_option['intQuantity'] == 0 && $this->_productsBatch['wpb_quantity_hold'] == 0 && $this->_warehouseProduct['wp_quantity'] + $this->_quantity == 0 && $this->_warehouseProduct['wp_quantity_hold'] == 0) {
                    $this->_wpstatus = 0;
                    $wpNote = '状态修改为不可用';
                }
            } elseif ($this->_option['intQuantity'] == 0 && $this->_productsBatch['wpb_quantity_hold'] == 0 && ($this->_warehouseProduct['wp_quantity'] + $this->_quantity) == 0 && $this->_warehouseProduct['wp_quantity_hold'] == 0) {
                /*
                * 查询相关此货架产品是否有未发货订单
                */
                $this->getByShelfStatus();
            }
            if ($this->_wpstatus == '0') {
                $wpNote = '状态修改为不可用';
            }
            $updateRow = array(
                'wp_status' => $this->_wpstatus,
                'wp_quantity' => $this->_warehouseProduct['wp_quantity'] + $this->_quantity,
                'wh_last_update' => $date,
            );
            if (!Warehouse_Service_Products::update($updateRow, $this->_warehouseProduct['wp_id'])) {
                $dbAdapter->rollback();
                $this->_error = '更新货架库存失败!';
                return false;
            } else {
                //货架使用日志
                $WarehouseProductsLog = array(
                    'wpl_refId' => 'edit stocket',
                    'warehouse_id' => $this->_productsBatch['warehouse_id'],
                    'ws_code' => $this->_productsBatch['ws_code'],
                    'wpl_proc_type' => $wpuProcType,
                    'wpl_note' => '原' . $this->_warehouseProduct['wp_quantity'] . '修改为' . ($this->_warehouseProduct['wp_quantity'] + $this->_quantity) . ' ' . $wpNote,
                );
                //写入货架使用日志
                if (!Warehouse_Service_Products::CreateWarehouseProductsLog($WarehouseProductsLog)) {
                    $dbAdapter->rollback();
                    $this->_error = '写入货架使用日志失败!wplog';
                    return false;
                }
            }

            //更新产品库存
            if (!Product_Service_ProductStocket::updateQuantity($this->_productsBatch['product_id'], $this->_quantity)) {
                $this->_error = '更新总库存失败!';
                $dbAdapter->rollback();
                return false;
            }

            $dbAdapter->commit();
            return true;
        } catch (Exception $e) {
            $dbAdapter->rollback();
            $this->_error = $e->getMessage();
            return false;
        }

    }

    /*
     * 判断货架是否还有其它未发货订单关联
     */
    private function getByShelfStatus()
    {
        $orderProduct = Order_Service_Product::getByCondition(array('product_id' => $this->_productsBatch['product_id']), 'orders_code', array('op_id desc'), 0, 0);
        foreach ($orderProduct as $key => $val) {
            $orders = Order_Service_Order::getByValue($val['orders_code'], 'orders_code', array('orders_code', 'orders_status', 'process_status'));
            if (isset($orders['orders_code']) && $orders['process_status'] < 5 && $orders['process_status'] > 1) {
                $opmModel = new Order_Model_OrderPickupMap();
                $orderPickupMap = $opmModel->getByfield('orders_code', $orders['orders_code']);
                foreach ($orderPickupMap as $k => $v) {
                    $wpbRow = Warehouse_Service_ProductsBatch::getById($v['wpb_id']);
                    //如果有订单关联，返回状态不可修改
                    if ($wpbRow['warehouse_id'] == $this->_warehouseProduct['warehouse_id'] && $wpbRow['product_id'] == $this->_warehouseProduct['product_id'] && $wpbRow['ws_code'] == $this->_warehouseProduct['ws_code']) {
                        //throw new Exception("存在相关订单");
                        $this->_wpstatus = 1;
                        return true;
                    }
                }
            }
        }
        //throw new Exception("不存在相关订单");
        $this->_wpstatus = 0;
        return false;
    }

    /*
     * 批次日志
     */
    private function createProductUseageLog($note = null, $procType = 1)
    {
        $add = array(
            'wpu_type' => 1,
            'wpu_proc_type' => $procType,
            'wpu_refId' => $this->_productsBatch['putaway_code'],
            'wpu_current_qty' => $this->_productsBatch['wpb_quantity'],
            'wpu_quantity' => abs($this->_quantity),
            'wpu_note' => $note,
            'wpb_id' => $this->_productsBatch['wpb_id'],
            'wpu_create_time' => date("Y-m-d H:i:s"),
        );
        if (!Warehouse_Service_ProductUseage::create($add)) {
            $this->_error = '写入批次日志失败!';
            return false;
        }
        return true;
    }

}